"use strict";
const pkgDir = require("pkg-dir").sync;
const npmInstall = require("npminstall");
const path = require("path");
const fse = require("fs-extra");
const pathExists = require("path-exists").sync;

const {isObject} = require("@unluna/utils");
const formatPath = require("@unluna/format-path");
const {getDefaultRegistry, getNpmLatestVersion, verAIsLaterThenVerB} = require("@unluna/get-npm-info");


class Package {
	constructor(options) {
		if (!options) {
			throw new Error("ERR: class Package options is required!".red);
		}
		if (!isObject(options)) {
			throw new Error("ERR: class Package options must be an object!".red);
		}
		// package的路径
		this.targetPath = options.targetPath;
		// 缓存路径（node_modules路径）
		this.storeDir = options.storeDir;
		// package的名称
		this.packageName = options.packageName;
		// package的版本
		this.packageVersion = options.packageVersion;
	}

	get cacheFilePath() {
		return path.resolve(this.storeDir, this.packageName);
	}

	async prepare() {
		if (this.storeDir && !pathExists(this.storeDir)) {
			fse.mkdirpSync(this.storeDir, {});
		}
		// 把 "latest" 转换为 npm 包的最新版本号
		if (this.packageVersion === "latest") {
			this.packageVersion = await getNpmLatestVersion(this.packageName);
		}
	}

	async exists() {
		if (this.storeDir) {
			await this.prepare();
			return pathExists(path.resolve(this.cacheFilePath, "package.json"));
		} else {
			return pathExists(this.targetPath);
		}
	}

	async install() {
		await this.prepare();
		return npmInstall({
			root: this.targetPath,
			storeDir: this.storeDir,
			registry: getDefaultRegistry(),
			pkgs: [
				{
					name: this.packageName,
					version: this.packageVersion
				}
			]
		});
	}

	async update() {
		await this.prepare();
		const currentNodeModulePkgJsonPath = path.resolve(this.cacheFilePath, "package.json");
		if (pathExists(currentNodeModulePkgJsonPath)) {
			const currentVer = require(currentNodeModulePkgJsonPath).version;
			// 更新
			if (verAIsLaterThenVerB(this.packageVersion, currentVer)) {
				console.log("package发现新版本，正在安装package...".red);
				await this.install()
			}
		} else {
			console.log("package更新失败，文件不存在，重新安装package...".red);
			await this.install()
		}
	}

	// 获取入口文件路径
	getRootFilePath() {
		// 找到package.json所在的目录
		const dir = pkgDir(this.targetPath);
		if (dir) {
			// package.json文件
			const pkgFile = require(path.resolve(dir, "package.json"));
			if (pkgFile && pkgFile.main) {
				// 兼容macOS/windows
				return formatPath(path.resolve(dir, pkgFile.main));
			}
		}
		return null;
	}
}

module.exports = Package;
